#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<random>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    Init();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::Init()
{
    pen.setColor(QColor(255,0,0));
    pen.setWidth(10);
    this->setFixedSize(1800,1300);
    srand(time(nullptr));
    label_sun=new QLabel(this);
    bgm_media=new QMediaPlayer(this);
    zom_com=new QMediaPlayer(this);
    plant_select=new QMediaPlayer(this);
    planted=new QMediaPlayer(this);
    eat_media=new QMediaPlayer(this);
    chan_media=new QMediaPlayer(this);
    erase_media=new QMediaPlayer(this);
    lose_media=new QMediaPlayer(this);
    lose_media->setMedia(QUrl::fromLocalFile("./music/lose.mp3"));
    lose_media->setVolume(100);
    bgm_media->setMedia(QUrl::fromLocalFile("./music/bgm.mp3"));
    erase_media->setMedia(QUrl::fromLocalFile("./music/erase_plant.mp3"));
    chan_media->setMedia(QUrl::fromLocalFile("./music/shovel.mp3"));
    bgm_media->play();
    zom_com->setMedia(QUrl::fromLocalFile("./music/zom_coming.mp3"));
    plant_select->setMedia(QUrl::fromLocalFile("./music/plant_select.mp3"));
    planted->setMedia(QUrl::fromLocalFile("./music/planted.mp3"));
    QFont font("微软雅黑",14);
    label_sun->setStyleSheet("color:red");
    label_sun->setFont(font);
    label_sun->setText(QString::number(sunsum));
    label_sun->setGeometry(628,8,200,200);
    timer_update=new QTimer(this);
    timer_update->start(update_fre);
    connect(timer_update,&QTimer::timeout,this,[&](){
        sum_time+=update_fre;
        update();
        label_sun->setText(QString::number(sunsum));
        //设置产出僵尸速度
        if(sum_time>=10*1000&&produce_zom_stage1==false) //前30秒
        {
            produce_zom_stage1=true;
            produce_zom_fre=produce_zom_fre1;
            return;
        }
        if(sum_time>=30*1000&&produce_zom_stage2==false)
        {
            produce_zom_fre=produce_zom_fre2;
            produce_zom_stage2=true;
            return;
        }
        if(sum_time>=60*1000&&produce_zom_stage3==false)
        {
            produce_zom_fre=produce_zom_fre3;
            produce_zom_stage3=true;
            return;
        }
    });
}


void MainWindow::dragPaint(QPainter *pa, QPixmap &pm)
{
    if(select_plant)
    {
        QString str;
        switch (select_type) {
        case Single_Pea:
            if(sunsum>=100)
                str=":/Peashooter/Peashooter1.png";
            break;
        case Sun_Flower:
            if(sunsum>=50)
                str=":/SunFlower/SunFlower1.png";
            break;
        case Snow_Pea:
            if(sunsum>=175)
                str=":/SnowPea/SnowPea1.png";
            break;
        case Nut:
            if(sunsum>=50)
                str=":/nut/1.png";
            break;
        case Potato_Mine:
            if(sunsum>=25)
                str=":/PotatoMine/PotatoMine1.png";
            break;
        default:
            break;
        }
        if(str.size())
        {
            Paint(str,cursor_x-50,cursor_y-50,100,100,pa,pm);
        }
    }
}

void MainWindow::initBackground(QPainter* pa,QPixmap& pm)
{

    Paint(":/background/Background.jpg",0,0,1800,1300,pa,pm);//初始化背景图片
    Paint(":/bar/bar.png",600,0,700,130,pa,pm);
    Paint(":chanzi/canzibar",1320,0,120,120,pa,pm);
    Paint(":chanzi/canzi.png",1328,35,100,50,pa,pm);
    for(int i=1;i<=5;i++)
    {
        QString str=":/Card/card_";
        str+=QString::number(i);
        str+=".png";
        Paint(str,703+(i-1)*75,0,75,120,pa,pm);
    }
    Zoms.resize(5);   //有5行僵尸
    Plants.resize(5);
    for(int i=0;i<5;i++)
    {
        Plants[i].resize(9);
    }

}
void MainWindow::Paint(QString str,int x, int y, int w, int h, QPainter *pa, QPixmap &pm)
{
    pm.load(str);
    pa->drawPixmap(x,y,w,h,pm);
}

void MainWindow::update_plant( QVector<QVector<plant*>> &Plants, QVector<QVector<zom> > &Zoms,QPainter* pa,QPixmap& pm)
{
    for(int i=0;i<5;i++)
    {
        for(int j=0;j<9;j++)
        {
            if(Plants[i][j]!=nullptr)
            {
                plant* p=Plants[i][j];
                int type=p->type;
                int life=p->life;
                int init_life=p->init_life;
                QString name=p->name;
                if(life<=0)
                {
                    delete Plants[i][j];
                    Plants[i][j]=nullptr;
                    continue;
                }

                int x=330+j*105;
                int y=170+i*210+60;

                float Life=life+0.00;         //绘制植物血量
                float Init_Life=init_life+0.00;
                float rate=Life/Init_Life;
                float true_length=life_length*rate;
                pa->drawLine(QLineF(x+10,y-20,x+10+true_length,y-20));
                int fps=p->fps;
                QString str=p->path;
                if(fps>0)
                {
                    str+=QString::number(fps);
                    str+=".png";
                }
                Paint(str,x,y,100,100,pa,pm);
                p->update(Zoms[i],Sunshines,pa,pm);

                int statue=p->statue;
                if(statue==2)
                {
                    if(p->boom_cartoon_pre>=p->boom_cartoon_fre)
                    {
                        delete Plants[i][j];
                        Plants[i][j]=nullptr;
                    }
                    else
                    {
                        p->boom_cartoon_pre+=update_fre;
                    }
                }
            }
        }
    }
}

void MainWindow::update_zom(QVector<QVector<zom> > &Zoms, QPainter *pa, QPixmap &pm)
{
    for(int i=0;i<Zoms.size();i++)
    {
        if(!Zoms[i].empty())
        {
            auto it=Zoms[i].begin();
            while(it!=Zoms[i].end())
            {
                zom& z= (*it);
                int x=z.x;
                int y=z.y;
                int life=z.life;
                int init_life=z.init_life;
                int number=z.number;
                int& eat_pre=z.eat_pre;
                int eat_fre=z.eat_fre;
                if(life<=0)
                {
                    if(eat_se.find(number)!=eat_se.end())
                    {
                        auto it=eat_se.begin();
                        while(it!=eat_se.end())
                        {
                            if((*it)==number)
                            {
                                eat_se.erase(it);
                                break;
                            }
                            ++it;
                        }
                        exist_eat--;
                    }
                    z.exist=false;
                }
                if(z.exist)
                {
                    float Life=life+0.00;         //绘制僵尸血量
                    float Init_Life=init_life+0.00;
                    float rate=Life/Init_Life;
                    float true_length=life_length*rate;
                    pa->drawLine(QLineF(x+70,y+10,x+70+true_length,y+10));
                }

                if(!z.exist)
                {

                    z.dead_pre=0;
                    QString str=":/Zom_Dead/";
                    str+=QString::number(z.dead_fps++);
                    str+=".png";
                    Paint(str,x,y,200,200,pa,pm);
                    if(z.dead_fps<=20)
                    {
                       ++it;
                    }
                    else
                    {
                        it=Zoms[i].erase(it);

                    }
                    continue;
                }
                if(x>=1240)
                {
                    QString str=":/Zom_Walk/";
                    str+=QString::number(z.fps++);
                    str+=".png";
                    if(z.fps>22)
                        z.fps=1;
                    Paint(str,x,y,200,200,pa,pm);
                    z.RenewPos();
                    continue;
                }
                int row=(y-170)/210;
                int col=(x-235)/105;
                if(row>=0&&row<5&&col>=0&&col<9&&Plants[row][col]!=nullptr)
                {
                    if(Plants[row][col]->type==2&&Plants[row][col]->statue==1)   //延时炸弹类植物
                    {
                        z.life-=Plants[row][col]->attack;
                        Plants[row][col]->statue=2;
                        continue;
                    }
                    if(eat_se.find(number)==eat_se.end())
                    {
                        eat_se.insert(number);
                        exist_eat++;
                    }
                    z.fps=1;
                    QString str=":Zom_Eat/";
                    str+=QString::number(z.eat_fps);
                    str+=".png";
                    Paint(str,x,y,200,200,pa,pm);
                    if(eat_pre>=eat_fre)
                    {
                        eat_pre=0;
                        z.eat_fps++;
                        if(z.eat_fps>21)
                            z.eat_fps=1;
                        plant* pl=Plants[row][col];
                        pl->life-=z.attack;
                    }
                    else
                        eat_pre+=update_fre;
                }
                else
                {
                    if(eat_se.find(number)!=eat_se.end())
                    {
                        auto it=eat_se.begin();
                        while(it!=eat_se.end())
                        {
                            if((*it)==number)
                            {
                                eat_se.erase(it);
                                break;
                            }
                            ++it;
                        }
                        exist_eat--;
                    }
                    z.eat_fps=1;
                    QString str=":/Zom_Walk/";
                    str+=QString::number(z.fps++);
                    str+=".png";
                    if(z.fps>22)
                        z.fps=1;
                    Paint(str,x,y,200,200,pa,pm);
                    if(x<=252)
                    {
                        failure=true;
                        return;
                    }
                    z.RenewPos();
                }
                ++it;
            }
        }
    }
}

void MainWindow::update_sun(QVector<sunshine> &Sunshines, QPainter *pa, QPixmap &pm)
{
    auto it=Sunshines.begin();
    while(it!=Sunshines.end())
    {
        sunshine& sun=(*it);
        int& fps=sun.fps;
        int x=sun.x;
        int y=sun.y;
        int& stay_pre=sun.stay_pre;
        if(stay_pre>=sun.stay_time)
        {
            it=Sunshines.erase(it);
            continue;
        }
        stay_pre+=update_fre;
        QString str=":/sunshine/";
        str+=QString::number(fps++);
        if(fps>29)
            fps=1;
        str+=".png";
        Paint(str,x,y,100,100,pa,pm);
        ++it;
    }
}

void MainWindow::Zom_Eat_sound()
{
    if(exist_eat>0)
    {
        int n=rand()%3;
        QString str="./music/eat";
        str+=QString::number(n);
        str+=".mp3";
        if(eat_media->state()==QMediaPlayer::StoppedState)
        {
            eat_media->setMedia(QUrl::fromLocalFile(str));
            eat_media->play();
        }
    }
}


void MainWindow::collectsun(QPainter* pa,QPixmap& pm)
{
    auto it=Collectshines.begin();
    while(it!=Collectshines.end())
    {
        int& x=(*it).x;
        int& y=(*it).y;
        int& fps=(*it).fps;
        int sun=(*it).sunnum;
        int per_x=(*it).per_x;
        int per_y=(*it).per_y;
        int des_x=(*it).des_x;
        int des_y=(*it).des_y;
        int collect_fre=(*it).collect_fre;
        int& collect_pre=(*it).collect_pre;
        QString str=":/sunshine/";
        if(fps>29)
            fps=1;
        str+=QString::number(fps++);
        str+=".png";
        Paint(str,x,y,100,100,pa,pm);
        if(abs(des_x-x)<=30&&abs(des_y-y)<=30)
        {
            sunsum+=sun;
            label_sun->setText(QString::number(sunsum));
            it=Collectshines.erase(it);
            continue;
        }
        if(collect_pre>=collect_fre)
        {
            collect_pre=0;
            x+=per_x;
            y+=per_y;
        }
        else
            collect_pre+=update_fre;
        ++it;
    }
    label_sun->setText(QString::number(sunsum));
}

void MainWindow::Auto_Collect_Sun()
{
    if(auto_collect_pre>=auto_collect_fre)
    {
        auto_collect_pre=0;
        for(int i=0;i<Sunshines.size();i++)
        {
                Collectshines.push_back(Sunshines[i]);
        }
        Sunshines.clear();
        label_sun->setText(QString::number(sunsum));
    }
    else
        auto_collect_pre+=update_fre;
}

void MainWindow::makezom()
{
    if(prepare_finish==false)
    {
        if(produce_zom_pre>=produce_prepare)
        {
            prepare_finish=true;
            zom_com->play();
        }
        else
            produce_zom_pre+=update_fre;
    }
    else
    {
        if(produce_zom_pre>=produce_zom_fre)
        {
            produce_zom_pre=0;
            int row=rand()%5;
            int x=1300;
            int y=170+row*210;
            zom z(x,y);
            z.number=rand()%(INT_MAX-1000);
            Zoms[row].push_back(z);
        }
        else
        {
            produce_zom_pre+=update_fre;

        }
    }



}

void MainWindow::mouseMoveEvent(QMouseEvent *me)
{
    cursor_x=me->x();
    cursor_y=me->y();
}

void MainWindow::mouseReleaseEvent(QMouseEvent *me)
{
    int x=me->x(),y=me->y();
    int row=(y-170)/210;
    int col=(x-330)/105;
    if(select_plant)
    {
        select_plant=false;
        if(x>=330&&x<=1256&&y>=170&&y<1236&&Plants[row][col]==nullptr)
        {
            select_plant=false;
            switch (select_type) {
            case Single_Pea:
                if(sunsum>=100)
                {
                    Plants[row][col]=new plant(1,"Single_Pea",row,col);
                    sunsum-=100;
                    label_sun->setText(QString::number(sunsum));
                    planted->play();
                }
                break;
            case Sun_Flower:
                if(sunsum>=50)
                {
                    Plants[row][col]=new plant(3,"Sun_Flower",row,col);
                    sunsum-=50;
                    label_sun->setText(QString::number(sunsum));
                    planted->play();
                }

                break;
            case Snow_Pea:
                if(sunsum>=175)
                {
                    Plants[row][col]=new plant(1,"Snow_Pea",row,col);
                    sunsum-=175;
                    label_sun->setText(QString::number(sunsum));
                    planted->play();
                }
                break;
            case Nut:
                if(sunsum>=50)
                {
                    Plants[row][col]=new plant(0,"Nut",row,col);
                    sunsum-=50;
                    label_sun->setText(QString::number(sunsum));
                    planted->play();
                }

                break;
            case Potato_Mine:
                if(sunsum>=25)
                {
                    Plants[row][col]=new plant(2,"Potato_Mine",row,col);
                    sunsum-=25;
                    label_sun->setText(QString::number(sunsum));
                    planted->play();
                }

                break;
            default:
                break;
            }
            return;
        }


    }
}

void MainWindow::paintEvent(QPaintEvent *pe)
{
    QPainter* pa=new QPainter(this);
    QPixmap pm;
    if(failure)
    {
        Paint(":fail/fail.png",0,0,1800,1300,pa,pm);
        bgm_media->stop();
        label_sun->close();
        if(exist_lose==false)
        {
            exist_lose=true;
            lose_media->play();
        }
        delete pa;
        return;
    }
    pa->setPen(pen);
    initBackground(pa,pm);
    Auto_Collect_Sun();
    dragPaint(pa,pm);
    makezom();
    update_plant(Plants,Zoms,pa,pm);
    update_zom(Zoms,pa,pm);
    Zom_Eat_sound();
    update_sun(Sunshines,pa,pm);

    collectsun(pa,pm);

    delete  pa;

}

void MainWindow::mousePressEvent(QMouseEvent *me)
{
    int x=me->x(),y=me->y();
    int row=(y-170)/210;
    int col=(x-330)/105;
    if(me->button()==Qt::LeftButton&&x>=703&&x<1286&&y<=120)
    {
        select_chan=false;
        int type=(x-703)/75;
        select_plant=true;
        plant_select->play();
        select_type=type;
        return;
    }
    if(me->button()==Qt::LeftButton&&x>=1332&x<1427&&y>=29&&y<=91)
    {
        chan_media->stop();
        chan_media->play();
        if(select_chan==false)
            select_chan=true;
        else
            select_chan=false;  //再次点击铲子则取消铲除
        return;
    }
    if(select_chan&&row>=0&&row<5&&col>=0&&col<9&&Plants[row][col]!=nullptr)
    {
        delete Plants[row][col];
        Plants[row][col]=nullptr;
        erase_media->stop();
        erase_media->play();
        select_chan=false;
        return;
    }
    if(me->button()==Qt::LeftButton)
    {
        auto it=Sunshines.begin();
        while(it!=Sunshines.end())
        {
            int s_x= (*it).x;
            int s_y= (*it).y;

            int sun=(*it).sunnum;
            if(abs(s_x-x)<=100&&abs(s_y-y)<=100)
            {
                sun_media.setMedia(QUrl::fromLocalFile("./music/sunshine.mp3"));
                sun_media.play();
                Collectshines.push_back(sunshine(sun,s_x,s_y)); //添加到收集阳光池中
                it=Sunshines.erase(it);
                continue;
            }
            ++it;
        }
    }
}

